package com.igeek.boot.controller;



import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.igeek.boot.anno.WMSLoganno;
import com.igeek.boot.config.LoginUser;
import com.igeek.boot.constant.RedisConstant;
import com.igeek.boot.entity.User;
import com.igeek.boot.exception.WisdomFactoryException;
import com.igeek.boot.mapper.UserMapper;
import com.igeek.boot.result.Result;
import com.igeek.boot.service.IUserService;
import com.igeek.boot.utils.JwtHelper;
import com.igeek.boot.utils.RedisUtils;
import com.igeek.boot.vo.LoginVO;
import com.igeek.boot.vo.PageQueryVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author jwj
 * @since 2023-12-26
 */
@RestController
@RequestMapping("/wisdom_factory/user")
@Api(tags = "用户表接口")
public class UserController {

    @Autowired
    private IUserService userService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Autowired
    private RedisUtils redisUtils;
    //用户登录接口
    @WMSLoganno(module = "用户",operation = "用户登录")
    @PostMapping("/login")
    @ApiOperation("用户登录接口")
    public Result login(@RequestBody User user) {
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername() , user.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        // 认证没通过
        if (Objects.isNull(authenticate)) {
            throw new WisdomFactoryException("用户名或密码错误!");
        }

        //认证通过，获取当前认证信息（包含：用户信息、已认证的状态、角色权限信息）
        LoginUser principal = (LoginUser)authenticate.getPrincipal();
        //获取用户信息
        user = principal.getUser();
        Integer userId = user.getId();
        String username = user.getUsername();
        //Redis中存储用户信息
        redisTemplate.opsForValue().set(RedisConstant.LOGIN_USER_TOKEN+"::"+userId , JSONUtil.toJsonStr(user));
        //生成token
        String token = JwtHelper.createToken(userId, username);
        Map<String,Object> map = new HashMap<>();
        map.put("token" , token);
        return new Result(true , "登录成功" , map);
    }

    //查询用户信息
    @PostMapping("/info")
    @ApiOperation("查询用户信息接口")
    public Result info(@RequestBody User user) {
        User userByUsername = userMapper.findUserByUsername(user.getUsername());
        return new Result(true, "查询成功", userByUsername);
    }

    //获取管理员姓名
    @ApiOperation("获取管理员姓名")
    @GetMapping("/findUserName")
    public Result findUserName() {
        //获取springSecurity上下文对象，包含认证的信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //获取封装的用户权限信息
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String username = loginUser.getUsername();
        String img = loginUser.getUser().getImg();
        HashMap<String, Object> map = new HashMap<>();
        map.put("username", username);
        map.put("img" , img);
        if(StringUtils.hasLength(username)){
            return new Result(true,"获取用户名成功",map);
        }
        return new Result(false,"获取用户名失败");
    }

    //管理员登出操作
    @WMSLoganno(module = "用户",operation = "用户登出")
    @ApiOperation("管理员登出")
    @GetMapping("/logout")
    public Result logout(){
        //获取springSecurity的上下文对象，包含认证的信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        Integer userId = loginUser.getUser().getId();
        //删除Redis中的权限信息
        redisTemplate.delete(RedisConstant.LOGIN_USER_TOKEN+"::"+userId);
        return new Result(true,"退出成功");
    }

    //根据用户名查询用户基本信息
    @GetMapping("/findUserByUsername")
    @ApiOperation("根据用户名查询用户基本信息")
    public Result findUserByUsername(@RequestParam("username") String username) {
        User user = userService.findUserByUsername(username);
        return new Result(true, "查询成功", user);
    }

    //上传文件图片  --> 通用
    @ApiOperation("上传个人信息图片")
    @PostMapping("/upload")
    public Result upload(@RequestPart("imgFile")MultipartFile imgFile) throws IOException {
        String img = userService.upload(imgFile);
        if(StringUtils.hasLength(img)){
            //在Redis中存储上传的图片信息
            redisUtils.sSet(RedisConstant.USER_PIC,img);
            return new Result(true,"文件上传成功",img);
        }
        return new Result(true,"文件上传失败");
    }

    //修改用户基本信息  --> 个人中心
    @WMSLoganno(module = "用户",operation = "用户修改个人信息")
    @PostMapping("/updateUserInfo")
    @ApiOperation("修改用户的基本信息")
    public Result updateUserInfo(@RequestBody User user) {
        boolean flag = userService.updateUserInfo(user);
        if(flag){
            return new Result(true, "修改成功");
        }
        return new Result(false, "修改失败");
    }

    //分页查询用户信息 --> 页面加载
    @GetMapping("/findUserPage")
    @ApiOperation("分页查询用户信息")
    public Result findUserPage(@ApiParam("分页条件") PageQueryVO pageQueryVO) {
        Page<User> pageModel = userService.findUserPage(pageQueryVO);
        return new Result(true, "查询成功",pageModel);
    }

    //添加用户信息  --> 用户信息管理
    @WMSLoganno(module = "用户",operation = "添加用户")
    @PostMapping("/addUserInfo")
    @ApiOperation("添加用户信息")
    public Result add(@RequestBody User user, @RequestParam("roleId") Integer roleId) {
        boolean flag = userService.addUserInfo(user,roleId);
        if(flag){
            //在Redis中存储套餐中的图片信息
            redisUtils.sSet(RedisConstant.USER_DB_PIC,user.getImg());
            return new Result(true, "添加成功");
        }
        return new Result(false, "添加失败");
    }

    //修改用户信息
    @WMSLoganno(module = "用户",operation = "管理员修改用户信息")
    @PutMapping("/updateUser")
    @ApiOperation("修改用户信息")
    public Result updateUser(@RequestBody User user ,@RequestParam("roleId") Integer roleId) {
        boolean flag = userService.updateUser(user,roleId);
        if(flag){
            return new Result(true, "修改成功");
        }
        return new Result(false, "修改失败");
    }
}
